package service

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/vueadmin/app/admin/internal/dto"
	"github.com/vueadmin/app/admin/internal/model"
	"github.com/vueadmin/app/admin/internal/svc"
	"github.com/vueadmin/app/admin/internal/vo"
	"github.com/vueadmin/utils/conv"
	"gorm.io/gorm"
)

type goodsService struct{
	svcCtx *svc.ServiceContext
}

func NewGoodsService(svcCtx *svc.ServiceContext) *goodsService {
	return &goodsService{
		svcCtx: svcCtx,
	}
}

/**
 * @description(数据列表)
 * @buildcode(true)
*/
func (p goodsService) GetPageList(req *dto.GoodsPageReq) ([]*vo.GoodsList, int64, error) {
	var (
		entity model.Goods
		list  []*vo.GoodsList
		count int64
	)
	query := p.svcCtx.Db.Model(&entity)
	if !conv.IsEmpty(req.GoodsId) {
		query = query.Where("goods_id = ?", req.GoodsId)
	}
	if !conv.IsEmpty(req.GoodsName) {
		query = query.Where("goods_name LIKE ?", "%"+req.GoodsName+"%")
	}
	if !conv.IsEmpty(req.SupplierId) {
		query = query.Where("supplier_id = ?", req.SupplierId)
	}
	if !conv.IsEmpty(req.ClassId) {
		query = query.Where("class_id = ?", req.ClassId)
	}
	if !conv.IsEmpty(req.Status) {
		query = query.Where("status = ?", req.Status)
	}
	if !conv.IsEmpty(req.CreateTime){
		query = query.Where("create_time BETWEEN ? AND ?", conv.UnixTime(req.CreateTime[0]), conv.UnixTime(req.CreateTime[1]))
	}
	orderBy := "goods_id desc"
	if !conv.IsEmpty(req.Sort) && !conv.IsEmpty(req.Order) {
		orderBy = fmt.Sprintf("%s %s", req.Sort, req.Order)
	}
	query = query.Preload("GoodsCata", func(db *gorm.DB) *gorm.DB {
		return db.Select("class_id,class_name")
	})
	query = query.Preload("Supplier", func(db *gorm.DB) *gorm.DB {
		return db.Select("supplier_id,supplier_name")
	})
	query.Count(&count)
	if err := query.Limit(req.Limit).Offset((req.Page - 1) * req.Limit).Order(orderBy).Find(&list).Error; err != nil {
		return nil, 0, err
	}
	return list, count, nil
}

/**
 * @description(修改排序开关)
 * @buildcode(true)
*/
func (p goodsService) UpdateExt(req map[string]interface{}) error {
	entity := model.Goods{}
	if err := p.svcCtx.Db.Model(&entity).Where("goods_id",conv.Int(req["goods_id"])).Updates(req).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(添加)
 * @buildcode(true)
*/
func (p goodsService) Add(req *dto.GoodsAddReq) (int, error) {
	entity := model.Goods{}
	entity.GoodsName = req.GoodsName
	entity.SupplierId = req.SupplierId
	entity.ClassId = req.ClassId
	entity.Pic = req.Pic
	entity.SalePrice = req.SalePrice
	entity.Images = req.Images
	entity.Status = req.Status
	entity.Cd = req.Cd
	entity.Store = req.Store
	entity.Sortid = req.Sortid
	entity.Detail = req.Detail
	entity.CreateTime = conv.NowUnix()

	if err := p.svcCtx.Db.Create(&entity).Error; err != nil {
		return 0, err
	}
	if entity.Sortid == 0 {
		if err := p.svcCtx.Db.Model(&entity).Update("sortid", entity.GoodsId).Error; err != nil {
			return 0, err
		}
	}
	return entity.GoodsId, nil
}

/**
 * @description(修改)
 * @buildcode(true)
*/
func (p goodsService) Update(req *dto.GoodsUpdateReq) error {
	entity := model.Goods{
		GoodsId: req.GoodsId,
	}
	query := p.svcCtx.Db
	if err := query.Limit(1).First(&entity).Error; err != nil {
		return err
	}
	entity.GoodsName = req.GoodsName
	entity.SupplierId = req.SupplierId
	entity.ClassId = req.ClassId
	entity.Pic = req.Pic
	entity.SalePrice = req.SalePrice
	entity.Images = req.Images
	entity.Status = req.Status
	entity.Cd = req.Cd
	entity.Store = req.Store
	entity.Sortid = req.Sortid
	entity.Detail = req.Detail
	entity.CreateTime = conv.UnixTime(req.CreateTime)

	field := conv.StringToSlice("goods_name,supplier_id,class_id,pic,sale_price,images,status,cd,store,sortid,detail,create_time", ",")

	if err := query.Select(field).Updates(&entity).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(获取修改详情)
 * @buildcode(true)
*/
func (p goodsService) GetUpdateInfo(req *dto.GoodsGetUpdateInfoReq) (*model.Goods, error) {
	entity := model.Goods{}
	if err := p.svcCtx.Db.Where("goods_id = ?",req.GoodsId).Limit(1).First(&entity).Error; err != nil {
		return nil, err
	}
	return &entity, nil
}

/**
 * @description(删除)
 * @buildcode(true)
*/
func (p goodsService) Delete(req *dto.GoodsDeleteReq) error {
	query := p.svcCtx.Db
	query = query.Where("goods_id IN ?", req.GoodsId)
	if err := query.Delete(&model.Goods{}).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(查看详情)
 * @buildcode(true)
*/
func (p goodsService) Detail(req *dto.GoodsDetailReq) (*vo.GoodsDetail, error) {
	var info vo.GoodsDetail
	query := p.svcCtx.Db.Model(&model.Goods{})
	query = query.Preload("GoodsCata", func(db *gorm.DB) *gorm.DB {
		return db.Select("class_id,class_name")
	})
	query = query.Preload("Supplier", func(db *gorm.DB) *gorm.DB {
		return db.Select("supplier_id,supplier_name")
	})
	if err := query.Where("goods_id = ?",req.GoodsId).Limit(1).First(&info).Error; err != nil {
		return nil, err
	}
	return &info, nil
}

/**
 * @description(查询sql下拉字段列表)
 * @buildcode(true)
*/
func (p goodsService) GetFieldList(c *gin.Context) (map[string]interface{}, error) {
	var (
		SupplierId []*vo.GoodsSupplierId
	)
	if err := p.svcCtx.Db.Raw(`select supplier_id,supplier_name from cd_supplier`).Scan(&SupplierId).Error; err != nil {
		return nil, err
	}
	data := make(map[string]interface{})
	data["supplier_ids"] = SupplierId
	return data, nil
}

/**
 * @description(查询所属分类联动)
 * @buildcode(true)
*/
func (p goodsService) GetClassIdList(req *dto.GoodsClassIdReq) ([]*vo.GoodsClassId, error) {
	var ClassId []*vo.GoodsClassId
	sql := fmt.Sprintf(`select class_id,class_name,pid from cd_goods_cata where supplier_id = %d`,req.SupplierId)
	if err := p.svcCtx.Db.Raw(sql).Scan(&ClassId).Error; err != nil {
		return nil, err
	}
	return p.getTreeClassId(ClassId,0),nil
}

/**
 * @description(格式所属分类树形结构)
 * @buildcode(true)
*/
func (p goodsService) getTreeClassId(list []*vo.GoodsClassId, pid int) []*vo.GoodsClassId {
	res := make([]*vo.GoodsClassId, 0)
	for _, v := range list {
		if v.Pid == pid {
			v.Children = p.getTreeClassId(list, v.ClassId)
			res = append(res, v)
		}
	}
	return res
}

